package com.winning.pmph.ctrl;

import cn.hutool.core.img.ImgUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.winning.pmph.entity.*;
import com.winning.pmph.mapper.*;
import com.winning.pmph.service.*;
import com.winning.pmph.utils.*;
import com.winning.pmph.vo.KnowledgeBindingInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Api(value = "知识库管理/知识词条")
@RestController
@RequestMapping("/pmph/action/knowledgeLib")
public class KnowledgeLibCtrl {

    @Resource
    private KnowledgeLibService knowledgeLibService;
    @Resource
    private KnowledgeLibFieldService knowledgeLibFieldService;
    @Resource
    private UserService userService;
    @Resource
    private TagService tagService;
    @Resource
    private RuleService ruleService;
    @Resource
    private RuleItemService ruleItemService;
    @Resource
    private TempKnowledgeService tempKnowledgeService;
    @Resource
    private ReleasedKnowledgeService releasedKnowledgeService;
    @Resource
    private ReleasedKnowledgeFieldService releasedKnowledgeFieldService;
    @Resource
    private KnowledgeService knowledgeService;
    @Resource
    private KnowledgeHistoryService knowledgeHistoryService;
    @Resource
    private KnowledgeFieldHistoryService knowledgeFieldHistoryService;
    @Resource
    private KnowledgeSyncRecordMapper knowledgeSyncRecordMapper;
    @Resource
    private KnowledgeSyncStatusMapper knowledgeSyncStatusMapper;
    @Resource
    private HistoryMapper historyMapper;
    @Resource
    private FieldCompareMapper fieldCompareMapper;
    @Resource
    private TaskItemService taskItemService;
    @Resource
    private PlatformService platformService;
    @Resource
    private KnowledgeBindingInfoMapper knowledgeBindingInfoMapper;
    @Resource
    private RocketMQProducerService rocketMQProducerService;
    @Resource
    private PlatformKnowledgeLibMapper platformKnowledgeLibMapper;

    @ApiOperation(value = "addRule", notes = "知识库单选字段保存接口")
    @GetMapping("addRule")
    public void addRule(String ruleName, String ruleType, String ruleItems, String deletedOptions) {

        try {
            JSONArray jsonArray = JSONArray.parseArray(ruleItems);
            List<RuleItem> ruleItemList = new ArrayList<>();
            for (Object object : jsonArray) {
                JSONObject jsonObject = (JSONObject) object;
                RuleItem item = new RuleItem();
                String id = jsonObject.getString("id");
                if (StringUtils.isNotBlank(id)) {
                    item.setId(jsonObject.getString("id"));
                }
                item.setName(jsonObject.getString("name"));
                item.setIdx(jsonObject.getIntValue("value"));
                item.setRuleId(jsonObject.getString("kindValue"));
                ruleItemList.add(item);
            }
            ruleService.addRule(ruleName, ruleType, ruleItemList, deletedOptions);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }

    @ApiOperation(value = "selectKnowledgeLibList", notes = "获取知识库id/名称接口")
    @GetMapping("selectKnowledgeLibList")
    public List<KnowledgeLib> selectKnowledgeLibList(String knowledgeLibName) {
        List<KnowledgeLib> knowledgeLibs = knowledgeLibService.lambdaQuery()
                .like(StringUtils.isNotEmpty(knowledgeLibName), KnowledgeLib::getName, knowledgeLibName).list();
        return knowledgeLibs;
    }

    /**
     * 获取分类数据
     */
    @ApiOperation(value = "selectTagData", notes = "知识库获取分类数据")
    @GetMapping("selectTagData")
    public List<Map<String, Object>> selectTagData(String queryString) {

        List<Map<String, Object>> tagCascadeList = new ArrayList<>();
        String sql = "select * from tag where PARENT_ID = ''";
        if (queryString != null) {
            sql += " and name like '%" + queryString + "%'";
        }

        List<Tag> tags = tagService.getBaseMapper().executeMultiSelect(sql);

        for (Tag tag : tags) {
            Map<String, Object> tagCascadeMap = new HashMap<>();
            tagCascadeMap.put("value", tag.getId());
            tagCascadeMap.put("label", tag.getName());
            tagCascadeList.add(tagCascadeMap);
        }
        return tagCascadeList;
    }

    /**
     * 获取选项数据
     */
    @ApiOperation(value = "selectRuleData", notes = "知识库获取选项数据")
    @GetMapping("selectRuleData")
    public List<Map<String, Object>> selectRuleData(String type, String ruleName) throws IOException {
        List<Map<String, Object>> ruleCascadeList = new ArrayList<>();

        List<Rule> ruleList = ruleService.lambdaQuery()
                .eq(StringUtils.isNotEmpty(type), Rule::getType, type)
                .like(StringUtils.isNotEmpty(ruleName), Rule::getName, ruleName)
                .orderByDesc(Rule::getUpdatedTime)
                .orderByAsc(Rule::getId).list();
        for (Rule rule : ruleList) {
            Map<String, Object> tagCascadeMap = new HashMap<>();
            tagCascadeMap.put("id", rule.getId());
            tagCascadeMap.put("title", rule.getName());
            List<RuleItem> ruleItemList = ruleService.queryItemByRuleId(rule.getId());
            List<Map<String, Object>> optionList = new ArrayList<>();
            for (RuleItem ruleItem : ruleItemList) {
                Map<String, Object> optionMap = new HashMap<>(16);
                optionMap.put("id", ruleItem.getId());
                optionMap.put("value", ruleItem.getIdx());
                optionMap.put("name", ruleItem.getName());
                optionMap.put("kindValue", ruleItem.getRuleId());
                optionList.add(optionMap);
            }

            tagCascadeMap.put("options", optionList);

            ruleCascadeList.add(tagCascadeMap);
        }
        return ruleCascadeList;
    }

    /**
     * 查询数据
     */
    @ApiOperation(value = "selectTempKnowledgeList", notes = "查询知识未发布页面列表接口")
    @GetMapping("selectTempKnowledgeList")
    public Page<TempKnowledge> selectTempKnowledgeList(Integer currentPage,
                                                       Integer pageNum, String all, String updateTime, String classify,
                                                       String platform, String version, String editor, String auditor,
                                                       String name, String id, String drugInfoLibCompany, Integer isCompose
    ) {

        Page page = new Page(currentPage, pageNum);
        String startTime = "";
        String endTime = "";
        if (StringUtils.isNotBlank(updateTime)) {
            startTime = (updateTime.split(",")[0].trim());
            endTime = (updateTime.split(",")[1].trim());
        }
        if (CollectionUtils.isEmpty(JSON.parseArray(classify))) {
            classify = "";
        }
        if (CollectionUtils.isEmpty(JSON.parseArray(platform))) {
            platform = "";
        }
        Page<TempKnowledge> tempKnowledgePage = tempKnowledgeService.getBaseMapper().queryTempKnowledgeList(page, classify, platform, version, editor, auditor, name, id, drugInfoLibCompany, isCompose, startTime, endTime);
        for (TempKnowledge tempKnowledge : tempKnowledgePage.getRecords()) {
            // 设置编辑人, 审核人;
            TaskItem lastTaskItem = taskItemService.getPassedTaskItemByKnowledgeId(tempKnowledge.getId());
            if (Objects.nonNull(lastTaskItem)) {
                tempKnowledge.setEditor(lastTaskItem.getEditor());
                List<String> auditorList = Stream.of(lastTaskItem.getFirstAuditor(), lastTaskItem.getSecondAuditor(), lastTaskItem.getThirdAuditor())
                        .filter(StringUtils::isNotEmpty).collect(Collectors.toList());
                tempKnowledge.setAuditorList(auditorList);
            }
        }
        return tempKnowledgePage;
    }

    @ApiOperation(value = "selectReleasedKnowledgeList", notes = "查询知识已发布列表页面接口")
    @GetMapping("selectReleasedKnowledgeList")
    public Page<ReleasedKnowledge> selectReleasedKnowledgeList(Integer currentPage,
                                                               Integer pageNum, String all, String updateTime, String classify,
                                                               String platform, String version, String editor, String auditor,
                                                               String name, String id, String queryStatus, String drugInfoLibCompany, Integer isCompose, Integer isRevised) {

        Page page = new Page(currentPage, pageNum);
        String startTime = "";
        String endTime = "";
        if (StringUtils.isNotBlank(updateTime)) {
            startTime = (updateTime.split(",")[0].trim());
            endTime = (updateTime.split(",")[1].trim());
        }
        if (CollectionUtils.isEmpty(JSON.parseArray(classify))) {
            classify = "";
        }
        if (CollectionUtils.isEmpty(JSON.parseArray(platform))) {
            platform = "";
        }

        //List<ReleasedKnowledge> list = knowledgeLibService.queryReleasedKnowledgeList(currentPage, pageNum, all, updateTime, classify, platform, version, editor, auditor, name, id, queryStatus, drugInfoLibCompany, intIsCompose);
        Page<ReleasedKnowledge> releasedKnowledgePage = releasedKnowledgeService.getBaseMapper().queryReleasedKnowledgeList(page, classify, platform, version, editor, auditor, name, id, drugInfoLibCompany, isCompose, startTime, endTime, isRevised);

        for (ReleasedKnowledge releasedKnowledge : releasedKnowledgePage.getRecords()) {
            // 设置编辑人, 审核人;
            TaskItem lastTaskItem = taskItemService.getLastFinishedTaskItemByKnowledgeId(releasedKnowledge.getId());
            if (Objects.nonNull(lastTaskItem)) {
                releasedKnowledge.setEditor(lastTaskItem.getEditor());
                List<String> auditorList = Stream.of(lastTaskItem.getFirstAuditor(), lastTaskItem.getSecondAuditor(), lastTaskItem.getThirdAuditor())
                        .filter(StringUtils::isNotEmpty).collect(Collectors.toList());
                releasedKnowledge.setAuditorList(auditorList);
            }
            List<TaskItem> taskItemList = taskItemService.getRevisionTaskItemByKnowledgeId(releasedKnowledge.getId());
            if (CollectionUtils.isNotEmpty(taskItemList) && taskItemList.size() > 0) {
                releasedKnowledge.setIsRevised(1);
            }
        }
        return releasedKnowledgePage;
    }

    /**
     * 新增接口
     */
    @ApiOperation(value = "newAdd", notes = "新增知识库接口")
    @PostMapping("newAdd")
    public KnowledgeLib newAdd(String knowledgeName, String tableData, String specialtyId) {
        KnowledgeLib knowledgeLib = knowledgeLibService.save(knowledgeName, tableData, "", specialtyId);
        return knowledgeLib;
    }

    /**
     * 导入接口
     */
    @ApiOperation(value = "export", notes = "导出接口")
    @GetMapping("export")
    public void export(String knowledgeName, String knowledgeLibId, HttpServletRequest request, HttpServletResponse response) throws IOException {
        request.setCharacterEncoding("UTF-8");
        response.setContentType("application/xls;charset=UTF-8");
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(knowledgeName + ".xls", "UTF-8"));
        List<KnowledgeLibField> list = new ArrayList<>();
        List<KnowledgeLibField> knowledgeLibFields = knowledgeLibFieldService.lambdaQuery().eq(KnowledgeLibField::getKnowledgeLibId, knowledgeLibId).list();
        for (KnowledgeLibField knowledgeLibField : knowledgeLibFields) {
            knowledgeLibField.setKind(knowledgeLibField.getKind());
            knowledgeLibField.setName(knowledgeLibField.getName());
            knowledgeLibField.setRequired(knowledgeLibField.getRequired());
            knowledgeLibField.setKindValue(knowledgeLibField.getKindValue());
            knowledgeLibField.setKindValue(knowledgeLibField.getKindValue());
            list.add(knowledgeLibField);
        }
        HSSFWorkbook wb = KnowledgeLibFiledUtils.createExcel(list, knowledgeName);
        String path = ApplicationContextUtil.BASE_DOWN_FORDER + knowledgeName + ".xls";
        OutputStream outputStream = new FileOutputStream(path);
        wb.write(outputStream);
        outputStream.close();
        try {
            wb.write(response.getOutputStream());
            response.getOutputStream().close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 编辑时获取数据库当前知识库id下的数据
     */
    @ApiOperation(value = "selectTableData", notes = "编辑时获取数据库当前知识库id下的数据")
    @GetMapping("selectTableData")
    public Map<String, Object> selectTableData(String id) throws IOException {
        List<KnowledgeLibField> fields = knowledgeLibFieldService.lambdaQuery()
                .eq(KnowledgeLibField::getKnowledgeLibId, id)
                .orderByAsc(KnowledgeLibField::getIndex).list();
        List<Map<String, Object>> tableDataMapList = new ArrayList<>();
        for (KnowledgeLibField field : fields) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", field.getId());
            map.put("name", field.getName());
            map.put("kind", String.valueOf(field.getKind()));
            map.put("kindValue", field.getKindValue());
            map.put("kindValue", field.getKindValue());
            map.put("required", String.valueOf(field.getRequired()));
            if (field.getKind() == KnowledgeLibField.FIELD_KIND_REFERENCE) {
                Tag tag = tagService.getById(field.getKindValue());
                map.put("fieldTypeDetail", tag.getName());
            } else if (field.getKind() == KnowledgeLibField.FIELD_KIND_ASSOCIATE_OTHER_KNOWLEDGE_LIB) {
                KnowledgeLib knowledgeLib = knowledgeLibService.getById(field.getKindValue());
                map.put("fieldTypeDetail", knowledgeLib.getName());
            }
            map.put("kindValue", field.getKindValue());
            map.put("index", field.getIndex());
            map.put("endIndex", fields.size() - 1);
            tableDataMapList.add(map);
        }
        String taskItemSql = "select knowledge_id from task_item where task_id in(select id from task where knowledge_lib_id='" + id + "') and deleted=0 and knowledge_id is not null and knowledge_id != '' group by knowledge_id";
        List<TaskItem> taskItems = taskItemService.getBaseMapper().executeMultiSelect(taskItemSql);
        Map<String, Object> responseMap = new HashMap<>();
        responseMap.put("tableData", tableDataMapList);
        responseMap.put("knowledgeLibId", id);
        responseMap.put("knowledgeCount", taskItems.size());
        return responseMap;
    }

    /**
     * 编辑时新增字段
     */
    @ApiOperation(value = "editAdd", notes = "编辑时新增字段接口")
    @PostMapping("editAdd")
    public boolean editAdd(String knowledgeName, String tableData, String id) {
        return knowledgeLibService.editSave(knowledgeName, tableData, id);
    }

    /**
     * 查询同步页面数据
     */
    @ApiOperation(value = "selectSynList", notes = "查询同步页面数据")
    @GetMapping("selectSynList")
    public Map<String, Object> selectSynList(Integer currentPage, int pageNum, String input, String platform,
                                             String status, String updateTime, String bindingPlatform, String id, String drugInfoLibCompany, String isCompose) {
        Map<String, Object> map = new HashMap<>();

        Integer intIsCompose = null;
        if (StringUtils.isNotBlank(isCompose)) {
            intIsCompose = Integer.valueOf(isCompose);
        }
        List<ReleasedKnowledge> list = knowledgeLibService.querySynList(currentPage, pageNum, input, platform, status, updateTime, bindingPlatform, id, drugInfoLibCompany, intIsCompose);
        // 总数据量
        int totalNum = knowledgeLibService.getTotalSynNum(input, platform, status, updateTime, bindingPlatform, id, drugInfoLibCompany, intIsCompose);
        map.put("totalNum", totalNum);
        map.put("tableData", list);
        return map;
    }

    /**
     * 获取所有平台数据
     */
    @ApiOperation(value = "selectPlatform", notes = "获取所有平台数据")
    @GetMapping("selectPlatform")
    public List<Map<String, Object>> selectPlatform() {
        List<Map<String, Object>> ruleCascadeList = new ArrayList<>();
        List<Platform> platforms = platformService.lambdaQuery().select(Platform::getId, Platform::getName).list();
        for (Platform platform : platforms) {
            Map<String, Object> tagCascadeMap = new HashMap<>();
            tagCascadeMap.put("value", platform.getId());
            tagCascadeMap.put("label", platform.getName());
            ruleCascadeList.add(tagCascadeMap);
        }
        return ruleCascadeList;
    }

    /**
     * 删除管理页面数据
     */
    @ApiOperation(value = "deleteTempAndReleaseById", notes = "删除管理页面数据")
    @GetMapping("deleteTempAndReleaseById")
    public void deleteTempAndReleaseById(String id, String status) {
        knowledgeLibService.deleteTempAndReleaseById(id, status);
    }

    /**
     * 查询某条知识是否被其他知识绑定
     */
    @ApiOperation(value = "selectBindingKnowledge", notes = "查询某条知识是否被其他知识绑定")
    @GetMapping("selectBindingKnowledge")
    public List<KnowledgeBindingInfo> selectBindingKnowledge(String knowledgeId) {
        List<KnowledgeBindingInfo> infoList = Lists.newArrayList();
        if (StringUtils.isNotBlank(knowledgeId)) {
            Knowledge knowledge = releasedKnowledgeService.getById(knowledgeId);
            if (knowledge == null) {
                knowledge = tempKnowledgeService.getById(knowledgeId);
            }
            if (knowledge == null) {
                return infoList;
            }
            String sql = "SELECT\n" +
                    "   tkf.ID AS knowledgeFieldId,\n" +
                    "   tkf.`NAME` AS knowledgeFieldName,\n" +
                    "   tk.ID AS knowledgeId,\n" +
                    "   tk.`NAME` AS knowledgeName,\n" +
                    "   kl.ID AS knowledgeLibId,\n" +
                    "   kl.`NAME` AS knowledgeLibName \n" +
                    "FROM\n" +
                    "   temp_knowledge_field AS tkf\n" +
                    "   LEFT JOIN temp_knowledge AS tk ON tk.ID = tkf.KNOWLEDGE_ID\n" +
                    "   LEFT JOIN knowledge_lib AS kl ON tk.KNOWLEDGE_LIB_ID = kl.ID \n" +
                    "WHERE\n" +
                    "   tkf.KIND = 8 \n" +
                    "   AND PROPERTY like '" + knowledge.getId() + "'" +
                    " UNION ALL\n" +
                    "SELECT\n" +
                    "   rkf.ID AS knowledgeFieldId,\n" +
                    "   rkf.`NAME` AS knowledgeFieldName,\n" +
                    "   rk.ID AS knowledgeId,\n" +
                    "   rk.`NAME` AS knowledgeName,\n" +
                    "   kl.ID AS knowledgeLibId,\n" +
                    "   kl.`NAME` AS knowledgeLibName \n" +
                    "FROM\n" +
                    "   released_knowledge_field AS rkf\n" +
                    "   LEFT JOIN released_knowledge AS rk ON rk.ID = rkf.KNOWLEDGE_ID\n" +
                    "   LEFT JOIN knowledge_lib AS kl ON rk.KNOWLEDGE_LIB_ID = kl.ID \n" +
                    "WHERE\n" +
                    "   rkf.KIND = 8 \n" +
                    "   AND PROPERTY like '" + knowledge.getId() + "' ";
            infoList = knowledgeBindingInfoMapper.executeMultiSelect(sql);
        }
        return infoList;
    }

    @ApiOperation(value = "selectKnowledgeLibPage", notes = "查询知识库列表接口")
    @GetMapping("selectKnowledgeLibPage")
    public Page<KnowledgeLib> selectKnowledgeLibPage(KnowledgeLib knowledgeLib) {
        Page<KnowledgeLib> knowledgeLibPage = knowledgeLibService.getKnowledgeLibPage(knowledgeLib);
        return knowledgeLibPage;
    }

    @ApiOperation(value = "delete", notes = "知识库列表删除接口")
    @GetMapping("delete")
    public void delete(String id) {
        knowledgeLibService.deleteStringByFieldId(id, "");
    }

    @ApiOperation(value = "selectExportApplyList", notes = "知识库导出知识结果列表")
    @GetMapping("selectExportApplyList")
    public IPage<KnowledgeAuditPack> selectExportApplyList(Integer currentPage, Integer pageSize, String name,
                                                           String knowledgeLibId, String createdTime, String exportType) {
        KnowledgeAuditPack knowledgeAuditPack = new KnowledgeAuditPack();
        knowledgeAuditPack.setName(name);
        knowledgeAuditPack.setKnowledgeLibId(knowledgeLibId);
        if (StringUtils.isNotBlank(createdTime)) {
            knowledgeAuditPack.setStartDate(createdTime.split(",")[0].trim());
            knowledgeAuditPack.setEndDate(createdTime.split(",")[1].trim());
        }
        if (StringUtils.isNotBlank(exportType)) {
            knowledgeAuditPack.setType(Integer.valueOf(exportType));
        }
        return knowledgeLibService.queryExportApplyList(new Page<>(currentPage, pageSize), knowledgeAuditPack);
    }

    @ApiOperation(value = "deleteExportApplyById", notes = "知识库导出知识结果列表删除接口")
    @GetMapping("deleteExportApplyById")
    public void deleteExportApplyById(String id) {
        // 取得知识导出申请表id
        knowledgeLibService.deleteExportApplyById(id);
    }

    @ApiOperation(value = "downloadExportApply", notes = "知识库导出知识结果列表下载接口")
    @GetMapping("downloadExportApply")
    public void downloadExportApply(String id, String name, String password, String downloadTotal, String type,
                                    String exclude, String knowledgeLibName, String includeDynamicField,
                                    String knowledgeLibId, HttpServletResponse response) throws UnsupportedEncodingException {
        KnowledgeAuditPack knowledgeAuditPack = new KnowledgeAuditPack();
        // 取得知识导出申请表id
        knowledgeAuditPack.setId(id);
        // 取得加密密码
        knowledgeAuditPack.setPassword(password);
        // 取得下载次数
        knowledgeAuditPack.setDownloadTotal(StringUtils.isBlank(downloadTotal) ? 0 : Integer.valueOf(downloadTotal));
        // 取得打包类型 1 excel  2 xml
        knowledgeAuditPack.setType(StringUtils.isBlank(type) ? 1 : Integer.valueOf(type));
        // 需要去除的打包的字段
        knowledgeAuditPack.setExclude(exclude);
        // 取得知识库名称
        knowledgeAuditPack.setKnowledgeLibName(knowledgeLibName);
        knowledgeAuditPack.setName(name);
        // 取得是否包含动态字段  当导出excel时，不导动态字段   导xml时，需要根据该字段判断是否导出动态字段
        knowledgeAuditPack.setIncludeDynamicField(StringUtils.isBlank(includeDynamicField) ? 0 : Integer.valueOf(includeDynamicField));
        // 取得知识库ID
        knowledgeAuditPack.setKnowledgeLibId(knowledgeLibId);
        response.setContentType("application/json; application/octet-stream");
        String zipFilePath = "";
        OutputStream ous = null;
        OutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            if (1 == knowledgeAuditPack.getType()) {
                response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("11.xlsx", "UTF-8"));
                knowledgeLibService.downloadExportApplyExcel(knowledgeAuditPack, outputStream);
            } else {
                zipFilePath = knowledgeLibService.downloadExportApplyXml(knowledgeAuditPack);
                File file = new File(zipFilePath + "/" + knowledgeAuditPack.getName() + ".zip");
                InputStream fis = new BufferedInputStream(new FileInputStream(file));
                byte[] buffer = new byte[fis.available()];
                fis.read(buffer);
                fis.close();
                response.reset();
                response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(knowledgeAuditPack.getKnowledgeLibName() + ".zip", "UTF-8"));
                response.addHeader("Content-Length", "" + file.length());
                ous = new BufferedOutputStream(outputStream);
                ous.write(buffer);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            ZipUtil.deleteDir(zipFilePath);
            if (ous != null) {
                try {
                    ous.flush();
                    ous.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != outputStream) {
                try {
                    outputStream.flush();
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 发布(单个)
     */
    @ApiOperation(value = "tempToRelease", notes = "知识未发布列表发布(单个)接口")
    @PostMapping("tempToRelease")
    public void tempToRelease(String id, String name) {
        knowledgeLibService.tempKnowledge2ReleaseKnowledge(id, name);
    }

    /**
     * 发布(批量)
     */
    @ApiOperation(value = "tempAllToRelease", notes = "知识未发布列表批量发布接口")
    @PostMapping("tempAllToRelease")
    public String tempAllToRelease(@RequestBody List<TempKnowledge> tempKnowledgeList) {
        int nameSuggestionCount = knowledgeLibService.TempAll2Release(tempKnowledgeList);
        String resultMsg = "发布成功" + (tempKnowledgeList.size() - nameSuggestionCount) + "条数据";
        if (nameSuggestionCount > 0) {
            resultMsg += ", 发布失败" + nameSuggestionCount + "条数据(存在未处理名称修改建议)";
        }
        return resultMsg;
    }

    /**
     * 获取日志数据
     */
    @ApiOperation(value = "selectLogTableData", notes = "知识查询日志列表")
    @GetMapping("selectLogTableData")
    public List<History> selectLogTableData(String id) {
        List<History> historyList = historyMapper.selectList(Wrappers.lambdaQuery(History.class).eq(History::getKnowledgeId, id)
                .orderByDesc(History::getUpdatedTime).orderByAsc(History::getId));
        return historyList;
    }

    /**
     * 获取同步日志数据
     */
    @ApiOperation(value = "selectSyncLogTableData", notes = "知识查询推送日志列表")
    @GetMapping("selectSyncLogTableData")
    public List<KnowledgeSyncRecord> selectSyncLogTableData(String id) {
        List<KnowledgeSyncRecord> knowledgeSyncRecords = knowledgeSyncRecordMapper.executeMultiSelect(
                "SELECT ksr.*, platform.name as platformName " +
                        " FROM knowledge_sync_record ksr " +
                        " join platform on ksr.PLATFORM_ID = platform.id " +
                        " where knowledge_id = '" + id + "' order by operated_time desc"
        );
        for (KnowledgeSyncRecord knowledgeSyncRecord : knowledgeSyncRecords) {
            User user = userService.getUserByUserName(knowledgeSyncRecord.getOperatedBy());
            knowledgeSyncRecord.setOperatedBy(user.getName());
        }
        return knowledgeSyncRecords;
    }


    /**
     * 获取同步日志数据
     */
    @ApiOperation(value = "selectSyncFailureLogTableData", notes = "知识查询推送失败日志列表")
    @GetMapping("selectSyncFailureLogTableData")
    public List<KnowledgeSyncStatus> selectSyncFailureLogTableData(String knowledgeLibId) {
        return getKnowledgeSyncStatusByKnowledgeLibId(knowledgeLibId);
    }

    private List<KnowledgeSyncStatus> getKnowledgeSyncStatusByKnowledgeLibId(String knowledgeLibId) {
        return knowledgeSyncStatusMapper.executeMultiSelect(
                "SELECT ksf.*, platform.NAME AS platformName, rk.`NAME` AS knowledge_name, " +
                        " case rk.knowledge_lib_id when '" + Const.DRUG_INFO_LIB_ID + "' then (select property from released_knowledge_field where rk.id = released_knowledge_field.knowledge_id and knowledge_lib_field_id = '" + Const.DRUG_INFO_LIB_COMPANY_ID + "') else '' end as 'drugInfoLibCompany'," +
                        " case rk.knowledge_lib_id when '" + Const.DRUG_INFO_LIB_ID + "' then (select property from released_knowledge_field where rk.id = released_knowledge_field.knowledge_id and knowledge_lib_field_id = '" + Const.DRUG_INFO_LIB_SOURCE_ID + "') else '' end as 'drugInfoLibSource' " +
                        " FROM knowledge_sync_status ksf " +
                        " LEFT JOIN platform ON ksf.PLATFORM_ID = platform.id " +
                        " LEFT JOIN released_knowledge rk on ksf.knowledge_id = rk.ID" +
                        // kind == 0, 推送失败, kind == 1 消费失败, kind == 2 未同步, kind == 3 同步成功
                        " where rk.knowledge_lib_id = '" + knowledgeLibId + "'" +
                        " and ksf.kind < 2 " +
                        " order by operated_time desc "
        );
    }

    /**
     * 获取某个知识库下的字段名称
     */
    @ApiOperation(value = "selectKnowledgeLibFieldName", notes = "获取某个知识库下的字段名称")
    @GetMapping("selectKnowledgeLibFieldName")
    public List<Map<String, Object>> selectKnowledgeLibFieldName(String id) {
        List<KnowledgeLibField> knowledgeLibFields = knowledgeLibFieldService.lambdaQuery().eq(KnowledgeLibField::getKnowledgeLibId, id).list();

        List<Map<String, Object>> resList = new ArrayList<>();
        for (KnowledgeLibField field : knowledgeLibFields) {
            Map<String, Object> fieldMap = new HashMap<>();
            fieldMap.put("id", field.getId());
            fieldMap.put("name", field.getName());
            resList.add(fieldMap);
        }
        return resList;
    }

    /**
     * 知识导出保存接口
     */
    @ApiOperation(value = "addExportKnowledge", notes = "知识导出保存接口")
    @PostMapping("addExportKnowledge")
    public void addExportKnowledge(String id, String select, Integer currentPage, Integer pageNum, String updateTime,
                                   String classify, String platform, String version, String createdBy, String updatedBy,
                                   String knowledgeName, String queryStatus, String drugInfoLibCompany, String isCompose,
                                   String nameSelection, String name, String cause, String type, String includeDynamicField
    ) {

        if (StringUtils.isBlank(select)) {
            String status = "published";

            Integer intInsCompose = null;
            if (StringUtils.isNotBlank(isCompose)) {
                intInsCompose = Integer.valueOf(isCompose);
            }
            List<ReleasedKnowledge> list = knowledgeLibService.queryReleasedKnowledgeList(currentPage, pageNum, status, updateTime, classify, platform, version, createdBy, updatedBy, knowledgeName, id, queryStatus, drugInfoLibCompany, intInsCompose);
            select = JSON.toJSONString(list);
        }

        boolean includeDynamicFields = includeDynamicField.equals("true");
        knowledgeLibService.saveKnowledgeExport(id, select, nameSelection, name, cause, type, includeDynamicFields);

    }

    @ApiOperation(value = "selectDelData", notes = "知识回收站列表接口")
    @GetMapping("selectDelData")
    public IPage<ReleasedKnowledge> selectDelData(Integer currentPage, Integer pageNum, String knowledgeLibId, String name, String updatedTime,
                                                  String updatedBy, String drugInfoLibCompany) {

        TempKnowledge tempKnowledge = new TempKnowledge();
        tempKnowledge.setKnowledgeLibId(knowledgeLibId);
        tempKnowledge.setName(name);
        tempKnowledge.setUpdatedBy(updatedBy);
        tempKnowledge.setDrugInfoLibCompany(drugInfoLibCompany);
        if (StringUtils.isNotBlank(updatedTime)) {
            tempKnowledge.setStartDate(updatedTime.split(",")[0].trim());
            tempKnowledge.setEndDate(updatedTime.split(",")[1].trim());
        }
        IPage<ReleasedKnowledge> releasedKnowledgeIPage = knowledgeLibService.queryDelList(new Page<>(currentPage, pageNum), tempKnowledge);
        return releasedKnowledgeIPage;
    }

    /**
     * 回收站彻底删除接口
     */
    @ApiOperation(value = "deleteReleasedKnowledge", notes = "知识回收站彻底删除接口")
    @GetMapping("deleteReleasedKnowledge")
    public void deleteReleasedKnowledge(String knowledgeLibId, String name, String updatedTime,
                                        String updatedBy, String id, String operationType) {
        TempKnowledge tempKnowledge = new TempKnowledge();
        tempKnowledge.setKnowledgeLibId(knowledgeLibId);
        tempKnowledge.setName(name);
        tempKnowledge.setUpdatedBy(updatedBy);
        if (StringUtils.isNotBlank(updatedTime)) {
            tempKnowledge.setStartDate(updatedTime.split(",")[0].trim());
            tempKnowledge.setEndDate(updatedTime.split(",")[1].trim());
        }
        String ids = "('" + id + "')";
        if ("all".equals(operationType)) {
            // 清空回收站
            List<ReleasedKnowledge> list = releasedKnowledgeService.getBaseMapper().queryDelList(new Page<>(), tempKnowledge).getRecords();
            if (CollectionUtils.isNotEmpty(list)) {
                ids = "('" + list.stream().map(ReleasedKnowledge::getId).collect(Collectors.joining("','")) + "')";
            }
        }
        knowledgeLibService.deleteReleasedKnowledge(ids);
    }

    /**
     * 回收站恢复接口
     */
    @ApiOperation(value = "recoverReleasedKnowledge", notes = "知识回收站恢复接口")
    @GetMapping("recoverReleasedKnowledge")
    public void recoverReleasedKnowledge(String ids) {
        knowledgeLibService.recoverReleasedKnowledge(ids);
    }

    @ApiOperation(value = "syncKnowledge", notes = "推送知识接口")
    @GetMapping("syncKnowledge")
    public Map<String, Object> syncKnowledge(String knowledgeId, String platformIdArray) {
        List<String> platformIdList = JSON.parseArray(platformIdArray, String.class);
        ReleasedKnowledge releasedKnowledge = releasedKnowledgeService.getById(knowledgeId);

        // 给releasedKnowledge对象设置fields
        String sql = "select * from released_knowledge_field where knowledge_id = '" + releasedKnowledge.getId() + "' order by hidden, id";
        List<KnowledgeField> releasedKnowledgeFields = Lists.newArrayList();
        releasedKnowledgeFieldService.getBaseMapper().executeMultiSelect(sql).forEach(releasedKnowledgeFields::add);
        releasedKnowledge.setKnowledgeFieldList(releasedKnowledgeFields);
        releasedKnowledge.setKnowledgeLibName(knowledgeLibService.getById(releasedKnowledge.getKnowledgeLibId()).getName());

        // 发送knowledge
        List<String> failedList = new ArrayList<>();
        for (String platformId : platformIdList) {
            rocketMQProducerService.sendKnowledge(platformId, releasedKnowledge, PMPHAppUtil.getCurrentUserEnName());
        }

        // 反馈结果
        Map<String, Object> resMap = new HashMap<>();
        resMap.put("failedList", failedList);
        if (failedList.size() == 0) {
            resMap.put("result", "success");
        } else {
            resMap.put("result", "failed");
        }
        return resMap;
    }

    @ApiOperation(value = "selectModifiedTempKnowledgeFields", notes = "日志页面查询内容日志接口")
    @GetMapping("selectModifiedTempKnowledgeFields")
    public Map<String, Object> selectModifiedTempKnowledgeFields(String knowledgeId, String status, Integer pageSize, Integer currentPage) {
        String knowledgeName = "";
        if (StringUtils.equals(status, "published")) {
            ReleasedKnowledge releasedKnowledge = releasedKnowledgeService.getById(knowledgeId);
            knowledgeName = releasedKnowledge.getName();
        } else {
            TempKnowledge tempKnowledge = tempKnowledgeService.getById(knowledgeId);
            knowledgeName = tempKnowledge.getName();
        }
        String sql = "select * from field_compare where knowledge_id = '" + knowledgeId
                + "' order by operation_date desc,id limit  " + currentPage * pageSize + " , " + pageSize;
        List<FieldCompare> fieldCompares = fieldCompareMapper.executeMultiSelect(sql);
        String totalNumSql = "select * from field_compare where knowledge_id = '" + knowledgeId + "'";
        List<FieldCompare> fieldCompares4TotalNum = fieldCompareMapper.executeMultiSelect(totalNumSql);

        List<Map<String, Object>> tableDataList = new ArrayList<>();
        for (FieldCompare fieldCompare : fieldCompares) {
            Map<String, Object> fieldMap = new HashMap<>();
            fieldMap.put("id", fieldCompare.getKnowledgeFieldId());
            fieldMap.put("operator", fieldCompare.getUserName());
            fieldMap.put("operationAction", fieldCompare.getOperation());
            fieldMap.put("operationField", fieldCompare.getKnowledgeFieldName());
            fieldMap.put("modification", fieldCompare.getModification() == null ? "-" : fieldCompare.getModification());
            String date = fieldCompare.getOperationDate();
            fieldMap.put("recordTime", date);
            tableDataList.add(fieldMap);
        }

        Map<String, Object> responseMap = new HashMap<>();
        responseMap.put("tableData", tableDataList);
        responseMap.put("totalNum", fieldCompares4TotalNum.size());
        responseMap.put("knowledgeName", knowledgeName);
        return responseMap;
    }

    @ApiOperation(value = "selectCompareData", notes = "日志页面对比接口")
    @GetMapping("selectCompareData")
    public Map<String, Object> selectCompareData(String fieldName, String modifiedDateTime) {
        String sql = "select * from field_compare where knowledge_field_name = '"
                + fieldName + "' and operation_date = '" + modifiedDateTime + "'";
        List<FieldCompare> fieldCompares = fieldCompareMapper.executeMultiSelect(sql);

        Map<String, Object> responseMap = new HashMap<>();
        responseMap.put("oldValue", fieldCompares.get(0).getOldValue());
        responseMap.put("newValue", fieldCompares.get(0).getNewValue());
        return responseMap;
    }

    @ApiOperation(value = "selectAllPlatforms", notes = "查询所有平台接口")
    @GetMapping("selectAllPlatforms")
    public Map<String, Object> selectAllPlatforms(String type, String knowledgeLibId) {
        List<PlatformKnowledgeLib> platformKnowledgeLibList = platformKnowledgeLibMapper.lambdaQuery()
                .eq(StringUtils.isNotEmpty(type), PlatformKnowledgeLib::getSystemType, type)
                .eq(StringUtils.isNotEmpty(knowledgeLibId), PlatformKnowledgeLib::getKnowledgeLibId, knowledgeLibId)
                .list();
        if (CollectionUtils.isEmpty(platformKnowledgeLibList)) {
            return null;
        }
        List<String> platFormIdList = platformKnowledgeLibList.stream()
                .map(PlatformKnowledgeLib::getPlatformId)
                .distinct()
                .collect(Collectors.toList());
        List<Platform> platforms = platformService.list()
                .stream().filter(t -> platFormIdList.contains(t.getId()))
                .collect(Collectors.toList());
        List<Map<String, Object>> platformList = new ArrayList<>();
        for (Platform platform : platforms) {
            Map<String, Object> platformMap = new HashMap<>();
            platformMap.put("id", platform.getId());
            platformMap.put("name", platform.getName());
            platformList.add(platformMap);
        }
        Map<String, Object> responseMap = new HashMap<>();
        responseMap.put("platforms", platformList);
        return responseMap;
    }

    @GetMapping("syncKnowledgeToTopic")
    public void syncKnowledgeToTopic(String knowledgeId, String platformId) {
        ReleasedKnowledge releasedKnowledge = releasedKnowledgeService.getById(knowledgeId);

        // 给releasedKnowledge对象设置fields
        releasedKnowledge.setKnowledgeLibName(knowledgeLibService.getById(releasedKnowledge.getKnowledgeLibId()).getName());

        // 发送knowledge
        rocketMQProducerService.sendKnowledge(platformId, releasedKnowledge, PMPHAppUtil.getCurrentUserEnName());

    }

    /**
     * 导出word模板
     *
     * @throws Exception 字段类型无法被识别
     */
    @ApiOperation(value = "exportWord", notes = "word模板导出")
    @GetMapping("exportWord")
    public String exportWord(String knowledgeLibId) throws Exception {
        File path = new File(ResourceUtils.getURL("classpath:").getPath());
        File upload = new File(path.getAbsolutePath(), "public/word/wordTemplate.docx");
        FileInputStream fileInputStream = new FileInputStream(upload);
        // 创建word文档对象
        XWPFDocument document = new XWPFDocument(fileInputStream);
        KnowledgeLib knowledgeLib = knowledgeLibService.getById(knowledgeLibId);
        List<KnowledgeLibField> knowledgeLibFields = knowledgeLibFieldService.lambdaQuery().eq(KnowledgeLibField::getKnowledgeLibId, knowledgeLibId).list();
        for (KnowledgeLibField knowledgeLibField : knowledgeLibFields) {
            XWPFParagraph metaParagraph = document.createParagraph();
            XWPFRun metaRun = metaParagraph.createRun();
            metaRun.setText(knowledgeLibField.getName());
            metaParagraph.setStyle("4");
            document.createParagraph(); // 插入空行
        }
        document.removeBodyElement(0);
        String filePath = ApplicationContextUtil.BASE_DOWN_FORDER + knowledgeLib.getName() + "模板.docx";
        File file = new File(filePath);
        // 保存word
        OutputStream outputStream = new FileOutputStream(ApplicationContextUtil.BASE_DOWN_FORDER + knowledgeLib.getName() + "模板.docx");
        document.write(outputStream);
        outputStream.close();
        return filePath;
    }

    /**
     * 未发布知识列表, 取消审核, 到未提交状态;
     */
    @ApiOperation(value = "cancelAudit", notes = "未发布知识列表, 取消审核, 到未提交状态;")
    @GetMapping("cancelAudit")
    public void cancelAudit(String knowledgeId) {
        tempKnowledgeService.getBaseMapper().executeUpdate("update temp_knowledge set status = 0 where id = '" + knowledgeId + "'");
    }

    @ApiOperation(value = "selectAllKnowledgeLib", notes = "获取所有知识库")
    @GetMapping("selectAllKnowledgeLib")
    public List<Map<String, String>> selectAllKnowledgeLib() {
        List<KnowledgeLib> knowledgeLibs = knowledgeLibService.list();
        List<Map<String, String>> resultList = Lists.newArrayList();
        for (KnowledgeLib item : knowledgeLibs) {
            Map<String, String> map = Maps.newConcurrentMap();
            map.put("value", item.getId());
            map.put("label", item.getName());
            resultList.add(map);
        }
        return resultList;
    }

    @ApiOperation(value = "TempAllRes", notes = "知识未发布列表一键发布接口")
    @GetMapping("TempAllRes")
    public String TempAllRes(String all,
                             String updateTime,
                             String classify,
                             String platform,
                             String version,
                             String editor,
                             String auditor,
                             String name,
                             String id,
                             String drugInfoLibCompany,
                             String isComposes) {
        Integer isCompose = null;
        if (StringUtils.isNotBlank(isComposes)) {
            isCompose = Integer.valueOf(isComposes);
        }
        List<TempKnowledge> tempKnowledgeList = knowledgeLibService.queryTempList(all, updateTime, classify, platform, version, editor, auditor, name, id, drugInfoLibCompany, isCompose);
        return tempAllToRelease(tempKnowledgeList);
    }

    @ApiOperation(value = "selectHistoryKnowledgeContent", notes = "知识已发布列表历史版本")
    @GetMapping("selectHistoryKnowledgeContent")
    public Map<String, Object> selectHistoryKnowledgeContent(String historyId) {
        if (StringUtils.isEmpty(historyId)) {
            throw new RuntimeException("historyId is null or empty string");
        }

        String sql = "select * from knowledge_field_history where knowledge_history_id = '" + historyId + "'";
        List<KnowledgeFieldHistory> knowledgeFieldHistories = knowledgeFieldHistoryService.lambdaQuery().eq(KnowledgeFieldHistory::getKnowledgeHistoryId, historyId).list();
        List<Map<String, Object>> fieldMapList = new ArrayList<>();
        for (KnowledgeFieldHistory history : knowledgeFieldHistories) {
            Map<String, Object> fieldMap = new HashMap<>();
            fieldMap.put("name", history.getName());
            String content = getFieldContent(history);
            fieldMap.put("content", content);
            fieldMapList.add(fieldMap);
        }

        KnowledgeHistory knowledgeHistory = knowledgeHistoryService.getById(historyId);

        Map<String, Object> resMap = new HashMap<>();
        resMap.put("name", knowledgeHistory.getName());
        resMap.put("fields", fieldMapList);
        return resMap;
    }

    private String getFieldContent(KnowledgeFieldHistory history) {
        if (history.getKind() == KnowledgeLibField.FIELD_KIND_STRINGTEXT) {
            return history.getProperty();
        } else if (history.getKind() == KnowledgeLibField.FIELD_KIND_REFERENCE) {
            if (history.getKindValue() == null) {
                return "";
            } else {
                String[] tagIds = history.getKindValue().split(",");
                StringBuilder stringBuilder = new StringBuilder();
                for (String tagId : tagIds) {
                    Tag tag = tagService.getById(tagId);
                    stringBuilder.append(tag.getName()).append(",");
                }
                return StringUtils.removeEnd(stringBuilder.toString(), ",");
            }
        } else if (history.getKind() == KnowledgeLibField.FIELD_KIND_DROPDOWNLIST) {
            RuleItem ruleItem = ruleItemService.getById(history.getProperty());
            if (Objects.isNull(ruleItem)) {
                return "";
            } else {
                return ruleItem.getName();
            }
        } else if (history.getKind() == KnowledgeLibField.FIELD_KIND_IMG) {
            String property = history.getProperty();
            return FieldCompareUtil.buildImage(property);
        } else if (history.getKind() == KnowledgeLibField.FIELD_KIND_DROPMULTILIST) {
            List<String> idList = JSON.parseArray(history.getProperty(), String.class);
            if (CollectionUtils.isEmpty(idList)) {
                return "";
            }
            List<RuleItem> ruleItemList = ruleItemService.lambdaQuery().in(RuleItem::getId, idList).list();
            return ruleItemList.stream().map(RuleItem::getName).collect(Collectors.joining(","));
        } else if (history.getKind() == KnowledgeLibField.FIELD_KIND_TEXTAREA) {
            return history.getProperty();
        } else if (history.getKind() == KnowledgeLibField.FIELD_KIND_RICHEDITOR) {
            return history.getProperty();
        } else if (history.getKind() == KnowledgeLibField.FIELD_KIND_MULTI_VALUE_INPUT) {
            String property = history.getProperty();
            return FieldCompareUtil.buildMultiValueInput(property);
        } else if (history.getKind() == KnowledgeLibField.FIELD_KIND_ASSOCIATE_OTHER_KNOWLEDGE_LIB
                || history.getKind() == KnowledgeLibField.FIELD_KIND_ASSOCIATE_CURRENT_KNOWLEDGE_LIB) {
            return FieldCompareUtil.buildAssociateKnowledge(history.getProperty());
        } else if (history.getKind() == KnowledgeLibField.FIELD_KIND_ASSOCIATE_PLATFORM) {
            String property = history.getProperty();
            return FieldCompareUtil.buildPlatforms(property);
        } else if (history.getKind() == KnowledgeLibField.FIELD_KIND_VIDEO) {
            return FieldCompareUtil.buildVideoHtml(history.getProperty());
        } else if (history.getKind() == KnowledgeLibField.FIELD_KIND_FILE) {
            return FieldCompareUtil.buildFiles(history.getProperty());
        } else {
            throw new RuntimeException("Illegal field kind: " + history.getKind());
        }
    }

    @ApiOperation(value = "selectKnowledgeHistory", notes = "知识已发布列表历史版本根据知识id展示内容")
    @GetMapping("selectKnowledgeHistory")
    public List<Map<String, Object>> selectKnowledgeHistory(String id) {
        if (StringUtils.isEmpty(id)) {
            throw new RuntimeException("Knowledge ID is null or empty string");
        }

        List<KnowledgeHistory> knowledgeHistoryList = knowledgeHistoryService.lambdaQuery().eq(KnowledgeHistory::getKnowledgeId, id).orderByAsc(KnowledgeHistory::getVersion).list();
        List<Map<String, Object>> historyMapList = new ArrayList<>();
        for (KnowledgeHistory history : knowledgeHistoryList) {
            Map<String, Object> historyMap = new HashMap<>();
            historyMap.put("historyId", history.getId());
            historyMap.put("version", history.getVersion());
            historyMap.put("date", history.getUpdatedTime());
            historyMapList.add(historyMap);
        }
        return historyMapList;
    }

    @ApiOperation(value = "selectEditTableData", notes = "知识同步状态计算")
    @GetMapping("selectEditTableData")
    public List<Map<String, Object>> selectEditTableData(String knowledgeId) {
        String sql = "select kss.*, p.name as platformName, p.status as platformStatus " +
                " from knowledge_sync_status kss " +
                " left join platform p on p.id = kss.platform_id " +
                " where kss.knowledge_id = '" + knowledgeId + "' ";
        List<KnowledgeSyncStatus> knowledgeSyncStatusList = knowledgeSyncStatusMapper.executeMultiSelect(sql);
        ReleasedKnowledge releasedKnowledge = releasedKnowledgeService.getById(knowledgeId);
        List<Map<String, Object>> platformList = new ArrayList<>();
        for (KnowledgeSyncStatus knowledgeSyncStatus : knowledgeSyncStatusList) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", knowledgeSyncStatus.getPlatformId());
            map.put("name", knowledgeSyncStatus.getPlatformName());
            map.put("status", knowledgeSyncStatus.getPlatformStatus());
            map.put("knowledgeId", knowledgeId);
            map.put("knowledgeName", releasedKnowledge.getName());
            if (knowledgeSyncStatus.getKind() == KnowledgeSyncStatus.FAILED_KIND_PRODUCER) {
                map.put("syncStatus", "推送失败");
            } else if (knowledgeSyncStatus.getKind() == KnowledgeSyncStatus.FAILED_KIND_CONSUMER) {
                map.put("syncStatus", "消费失败");
            } else if (knowledgeSyncStatus.getKind() == KnowledgeSyncStatus.KIND_SUCCESS) {
                map.put("syncStatus", "成功");
            } else if (knowledgeSyncStatus.getKind() == KnowledgeSyncStatus.FAILED_KIND_WAITING) {
                map.put("syncStatus", "未同步");
            }
            platformList.add(map);
        }
        return platformList;

    }

    @ApiOperation(value = "afreshSync", notes = "推送列表重新推送接口")
    @GetMapping("afreshSync")
    public void afreshSync(String platformId, String knowledgeId) {
        ReleasedKnowledge releasedKnowledge = releasedKnowledgeService.getById(knowledgeId);
        releasedKnowledge.setKnowledgeLibName(knowledgeLibService.getById(releasedKnowledge.getKnowledgeLibId()).getName());
        rocketMQProducerService.sendKnowledge(platformId, releasedKnowledge, PMPHAppUtil.getCurrentUserEnName());
    }

    @ApiOperation(value = "syncKnowledgesToPlatforms", notes = "单条知识推送接口")
    @PostMapping("syncKnowledgesToPlatforms")
    public String syncKnowledgesToPlatforms(String syncToPlatformType, String knowledgeLibId,
                                            String knowledgeId,
                                            String selectedKnowledges,
                                            String searchParam,
                                            String bindingPlatform) {

        List<ReleasedKnowledge> selectedKnowledge = JSONArray.parseArray(selectedKnowledges, ReleasedKnowledge.class);
        JSONObject searchParams = JSON.parseObject(searchParam);
        String username = PMPHAppUtil.getCurrentUserEnName();
        ExecutorServiceFactory.getInstance().submit(() -> {
            knowledgeLibService.syncKnowledgesToPlatforms(syncToPlatformType,
                    knowledgeLibId, selectedKnowledge, bindingPlatform, searchParams, username, knowledgeId);
        });
        return "推送任务提交成功, 请稍后查看推送状态";
    }

    @ApiOperation(value = "selectCheckRepeatName", notes = "检查知识库名称是否重复")
    @GetMapping("selectCheckRepeatName")
    public Boolean selectCheckRepeatName(String name) {
        Integer count = knowledgeLibService.lambdaQuery().eq(KnowledgeLib::getName, name).count();
        return count > 0;
    }

    @ApiOperation(value = "multiInsertTaskItem", notes = "知识修订接口")
    @PostMapping("multiInsertTaskItem")
    public String multiInsertTaskItem(String editType, String selectedKnowledgeIds, String taskId, String remark, String searchParams) {
        JSONObject searchParam = JSON.parseObject(searchParams);
        String username = PMPHAppUtil.getCurrentUserEnName();
        List<ReleasedKnowledge> releasedKnowledgeList = null;
        // 批量修订;
        if (Objects.equals("multi", editType)) {
            releasedKnowledgeList = releasedKnowledgeService.lambdaQuery().in(ReleasedKnowledge::getId, JSON.parseArray(selectedKnowledgeIds, String.class)).list();
        } else {
            // 一键修订, 查询当前搜索条件的知识;
            String sql = "select *," +
                    "case knowledge_lib_id when '" + Const.DRUG_INFO_LIB_ID + "' then (select property from released_knowledge_field where released_knowledge.id = released_knowledge_field.knowledge_id and knowledge_lib_field_id = '" + Const.DRUG_INFO_LIB_COMPANY_ID + "') else '' end as 'drugInfoLibCompany'," +
                    "case knowledge_lib_id when '" + Const.DRUG_INFO_LIB_ID + "' then (select property from released_knowledge_field where released_knowledge.id = released_knowledge_field.knowledge_id and knowledge_lib_field_id = '" + Const.DRUG_INFO_LIB_SOURCE_ID + "') else '' end as 'drugInfoLibSource' " +
                    " from released_knowledge where deleted = 0 and knowledge_lib_id = " + "'" + searchParam.getString("id") + "'";
            sql = knowledgeLibService.getReleaseSearch(searchParam.getString("updateTime"),
                    searchParam.getString("classify"),
                    searchParam.getString("platform"),
                    searchParam.getString("version"),
                    searchParam.getString("editor"),
                    searchParam.getString("auditor"),
                    searchParam.getString("name"), sql,
                    searchParam.getString("drugInfoLibCompany"),
                    searchParam.getInteger("isCompose"));
            releasedKnowledgeList = releasedKnowledgeService.getBaseMapper().executeMultiSelect(sql);
        }
        List<ReleasedKnowledge> finalReleasedKnowledgeList = releasedKnowledgeList;
        // 查询当前知识库, 正在编辑的知识;
        String sql = "select * from task_item " +
                " join task on task_item.task_id = task.id " +
                " where task.knowledge_lib_id = '" + searchParam.getString("id") + "' " +
                " and task.status != " + Task.STATUS_FINISHED +
                " and task.deleted = 0 " +
                " and task_item.status != " + TaskItem.STATUS_RELEASED;
        List<TaskItem> taskItemList = taskItemService.getBaseMapper().executeMultiSelect(sql);
        // taskItems 转为知识id集合
        Set<String> knowledgeInProcessIdSet = taskItemList.stream().map(TaskItem::getKnowledgeId).filter(org.apache.commons.lang3.StringUtils::isNotEmpty).collect(Collectors.toSet());
        List<String> revisedSuccessList = new ArrayList<>();
        List<String> revisedFailureList = new ArrayList<>();
        for (ReleasedKnowledge releasedKnowledge : finalReleasedKnowledgeList) {
            if (!knowledgeInProcessIdSet.contains(releasedKnowledge.getId())) {
                revisedSuccessList.add(releasedKnowledge.getId());
            } else {
                revisedFailureList.add(releasedKnowledge.getId());
            }
        }
        ExecutorServiceFactory.getInstance().
                submit(() -> knowledgeLibService.multiInsertTaskItem(taskId, remark, username, finalReleasedKnowledgeList, knowledgeInProcessIdSet));
        return "修订成功！您修订知识" + revisedSuccessList.size() + "条,请稍后查看任务状态,处在已修订的知识为" + revisedFailureList.size() + "条";
    }

    @ApiOperation(value = "selectBindingField", notes = "查询选项是否被其他知识引用接口")
    @GetMapping("selectBindingField")
    public List<ReleasedKnowledgeField> selectBindingField(String id, String kindValue, String isSingle) {
        boolean isSingles = Boolean.parseBoolean(isSingle);
        List<ReleasedKnowledgeField> fieldList;
        if (isSingles) {
            String sql =
                    "select ID, NAME from temp_knowledge_field where KIND = " + KnowledgeLibField.FIELD_KIND_DROPDOWNLIST + " and PROPERTY = '" + id + "' and KIND_VALUE = '" + kindValue + "' " +
                            "union\n" +
                            "select ID, NAME from released_knowledge_field where KIND = " + KnowledgeLibField.FIELD_KIND_DROPDOWNLIST + " and PROPERTY = '" + id + "' and KIND_VALUE = '" + kindValue + "' ";
            fieldList = releasedKnowledgeFieldService.getBaseMapper().executeMultiSelect(sql);
        } else {
            String sql =
                    "select ID, NAME from temp_knowledge_field where KIND = " + KnowledgeLibField.FIELD_KIND_DROPMULTILIST + " and PROPERTY = '" + id + "' and KIND_VALUE = '" + kindValue + "' " +
                            "union\n" +
                            "select ID, NAME from released_knowledge_field where KIND = " + KnowledgeLibField.FIELD_KIND_DROPMULTILIST + " and PROPERTY = '" + id + "' and KIND_VALUE = '" + kindValue + "' ";
            fieldList = releasedKnowledgeFieldService.getBaseMapper().executeMultiSelect(sql);
        }
        return fieldList;
    }

    /**
     * 查询tag类型字段;
     *
     * @param knowledgeLibId
     */
    @ApiOperation(value = "selectTagFieldList", notes = "查询tag类型字段接口")
    @GetMapping("selectTagFieldList")
    public List<KnowledgeLibField> selectTagFieldList(String knowledgeLibId) {
        List<KnowledgeLibField> knowledgeLibFieldList = knowledgeLibFieldService.lambdaQuery()
                .eq(KnowledgeLibField::getKnowledgeLibId, knowledgeLibId)
                .eq(KnowledgeLibField::getKind, KnowledgeLibField.FIELD_KIND_REFERENCE).list();
        return knowledgeLibFieldList;
    }

    @ApiOperation(value = "downloadZip", notes = "知识导出结果下载zip包类型接口")
    @GetMapping("downloadZip")
    public void downloadZip(String knowledgeLibId, HttpServletRequest request, HttpServletResponse response) throws Exception {
        KnowledgeLib knowledgeLib = knowledgeLibService.getById(knowledgeLibId);
        request.setCharacterEncoding("UTF-8");
        List<KnowledgeLibField> list = new ArrayList<>();
        List<KnowledgeLibField> knowledgeLibFields = knowledgeLibFieldService.lambdaQuery().eq(KnowledgeLibField::getKnowledgeLibId, knowledgeLibId).list();
        for (KnowledgeLibField knowledgeLibField : knowledgeLibFields) {
            knowledgeLibField.setKind(knowledgeLibField.getKind());
            knowledgeLibField.setName(knowledgeLibField.getName());
            knowledgeLibField.setRequired(knowledgeLibField.getRequired());
            knowledgeLibField.setKindValue(knowledgeLibField.getKindValue());
            knowledgeLibField.setKindValue(knowledgeLibField.getKindValue());
            list.add(knowledgeLibField);
        }
        HSSFWorkbook wb = KnowledgeLibFiledUtils.createExcel(list, knowledgeLib.getName());
        String path = ApplicationContextUtil.BASE_DOWN_FORDER + knowledgeLib.getName() + ".xlsx";
        OutputStream outputStream = new FileOutputStream(path);
        wb.write(outputStream);
        outputStream.close();
        String wordPath = exportWord(knowledgeLibId);

        String excelName = StringUtils.substringAfterLast(path, "/");
        String wordName = StringUtils.substringAfterLast(wordPath, "/");

        String zipPath = ApplicationContextUtil.BASE_DOWN_FORDER + "knowledgeLibFile/";
        if (!new File(zipPath).exists()) {
            new File(zipPath).mkdirs();
        }
        FileUtils.copyFile(new File(path), new File(zipPath + excelName));
        FileUtils.copyFile(new File(wordPath), new File(zipPath + wordName));
        ZipUtil.toZip(zipPath, "", knowledgeLib.getName());

        InputStream input = new FileInputStream(new File(ApplicationContextUtil.BASE_DOWN_FORDER + "knowledgeLibFile/" + knowledgeLib.getName() + ".zip"));
        response.setContentType("application/docx;charset=UTF-8");
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(knowledgeLib.getName() + ".zip", "UTF-8"));
        ServletOutputStream outStream = response.getOutputStream();
        int byteRead = 0;
        byte[] buffer = new byte[512];
        while ((byteRead = input.read(buffer)) != -1) {
            outStream.write(buffer, 0, byteRead);
        }
        input.close();
        outStream.close();
        FileUtils.deleteDirectory(new File(zipPath));
    }

    @ApiOperation(value = "wordExport", notes = "知识已发布发布word导出接口，只有新媒体文章供稿库才显示")
    @GetMapping("wordExport")
    public void wordExport(String knowledgeId, HttpServletResponse response) {
        File tempFile = null;
        try {
            List<ReleasedKnowledgeField> list = releasedKnowledgeFieldService.lambdaQuery().eq(StringUtils.isNotBlank(knowledgeId), ReleasedKnowledgeField::getKnowledgeId, knowledgeId).list();
            String value = "";
            JSONArray source = null;
            String editor = "";
            for (ReleasedKnowledgeField releasedKnowledgeField : list) {
                if (StringUtils.equals(releasedKnowledgeField.getName(), "正文")) {
                    value = releasedKnowledgeField.getProperty();
                    source = releasedKnowledgeField.getSource();
                } else if (StringUtils.equals(releasedKnowledgeField.getName(), "作者")) {
                    editor = releasedKnowledgeField.getProperty();
                }
            }
            ClassPathResource classPathResource = new ClassPathResource("public/word/manuscript.docx");
            tempFile = new File("temp_manuscript.docx");
            FileUtils.copyInputStreamToFile(classPathResource.getInputStream(), tempFile);
            FileInputStream fileInputStream = new FileInputStream(tempFile);
            XWPFDocument document = new XWPFDocument(fileInputStream);
            document.removeBodyElement(0);
            XWPFParagraph metaParagraph = document.createParagraph();
            XWPFRun metaRun = metaParagraph.createRun();
            metaRun.setText(list.get(0).getProperty());
            metaParagraph.setStyle("19");
            Document doc = Jsoup.parse(value);
            Elements contentEls = doc.body().children();
            for (int i = 0; i < contentEls.size(); i++) {
                Element currentEl = contentEls.get(i);
                Elements img = contentEls.get(i).getElementsByTag("img");
                if (img.size() > 0) {
                    XWPFParagraph Paragraph = document.createParagraph();
                    XWPFRun ImgRun = Paragraph.createRun();
                    String imgSrc = img.attr("src");
                    String src = StringUtils.substringAfter(imgSrc, "=");
                    String fileName = StringUtils.substringAfterLast(imgSrc, "/");
                    String srcPath = ApplicationContextUtil.BASE_DOWN_FORDER + src;
                    File file = new File(srcPath);
                    if (file.exists()) {
                        InputStream inputStream = new FileInputStream(file);
                        byte[] bytes = IOUtils.toByteArray(inputStream);
                        BufferedImage image = ImgUtil.read(new ByteArrayInputStream(bytes));
                        int width = image.getWidth() * 3600;
                        int height = image.getHeight() * 3600;
                        ImgRun.addPicture(new ByteArrayInputStream(bytes), XWPFDocument.PICTURE_TYPE_PNG, fileName, width, height);
                        Paragraph.setStyle("19");
                        fileInputStream.close();
                    }
                } else if (currentEl.toString().contains("p_title")) {
                    XWPFParagraph titleParagraph = document.createParagraph();
                    XWPFRun titleRun = titleParagraph.createRun();
                    titleRun.setText("图题：" + currentEl.text());
                    titleParagraph.setStyle("24");
                } else if (currentEl.toString().contains("p_note")) {
                    XWPFParagraph noteParagraph = document.createParagraph();
                    XWPFRun noteRun = noteParagraph.createRun();
                    noteRun.setText("图注：" + currentEl.text());
                    noteParagraph.setStyle("24");
                } else if (currentEl.toString().contains("t_title")) {
                    XWPFParagraph tableTitleParagraph = document.createParagraph();
                    XWPFRun tableTitleRun = tableTitleParagraph.createRun();
                    tableTitleRun.setText("表题：" + currentEl.text());
                    tableTitleParagraph.setStyle("24");
                } else if (currentEl.toString().contains("t_note")) {
                    XWPFParagraph tableNoteParagraph = document.createParagraph();
                    XWPFRun tableNoteRun = tableNoteParagraph.createRun();
                    tableNoteRun.setText("表注：" + currentEl.text());
                    tableNoteParagraph.setStyle("24");
                } else {
                    XWPFParagraph fieldIdParagraph = document.createParagraph();
                    XWPFRun fieldIdMetaRun = fieldIdParagraph.createRun();
                    fieldIdMetaRun.setText(currentEl.text());
                    fieldIdParagraph.setStyle("20");
                }
            }
            String sourceStr = "";
            for (int j = 0; j < source.size(); j++) {
                JSONObject sourceJson = source.getJSONObject(j);
                String name = sourceJson.getString("name");
                String isbn = sourceJson.getString("isbn");
                String version = sourceJson.getString("version");
                XWPFParagraph sourceParagraph = document.createParagraph();
                XWPFRun sourceRun = sourceParagraph.createRun();
                sourceParagraph.setStyle("22");
                if (StringUtils.isNotBlank(name)) {
                    sourceStr += name + ",";
                }
                if (StringUtils.isNotBlank(version)) {
                    sourceStr += version + ",";
                }
                if (StringUtils.isNotBlank(isbn)) {
                    sourceStr += isbn;
                }
                if (j > 0) {
                    sourceRun.setText(sourceStr);
                } else {
                    sourceRun.setText("知识来源：" + sourceStr);
                }
                sourceStr = "";
            }
            XWPFParagraph editParagraph = document.createParagraph();
            XWPFRun editRun = editParagraph.createRun();
            editParagraph.setStyle("22");
            editRun.setText("主编:" + editor);

            response.setContentType("application/docx;charset=UTF-8");
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(list.get(0).getProperty() + ".docx", "UTF-8"));
//        // 保存word
            OutputStream outputStream = response.getOutputStream();
            document.write(outputStream);
            outputStream.close();
        } catch (Exception e) {
            throw new RuntimeException("导出异常");
        } finally {
            if (null != tempFile) {
                tempFile.delete();
            }
        }
    }
}